package com.zbkj.service.service.course.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.model.course.Course;
import com.zbkj.common.model.course.CourseProduction;
import com.zbkj.common.model.course.CourseProductionImg;
import com.zbkj.common.model.course.CourseProductionLike;
import com.zbkj.common.model.system.SystemAttachment;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.course.CourseProductionRequest;
import com.zbkj.common.request.course.CourseProductionSearchRequest;
import com.zbkj.common.response.CommonResult;
import com.zbkj.common.response.course.CourseProductionResponse;
import com.zbkj.common.response.course.CourseUserResponse;
import com.zbkj.service.dao.CourseProductionDao;
import com.zbkj.service.service.SystemAttachmentService;
import com.zbkj.service.service.SystemConfigService;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.course.CourseProductionImgService;
import com.zbkj.service.service.course.CourseProductionLikeService;
import com.zbkj.service.service.course.CourseProductionService;
import com.zbkj.service.service.course.UserTaskService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mr.Zhang
 * @description CourseProductionServiceImpl 接口实现
 * @date 2022-07-22
 */
@Service
public class CourseProductionServiceImpl extends ServiceImpl<CourseProductionDao, CourseProduction> implements CourseProductionService {

    @Resource
    private CourseProductionDao dao;

    @Autowired
    private UserService userService;

    @Autowired
    private CourseProductionImgService courseProductionImgService;

    @Autowired
    private CourseProductionLikeService productionLikeService;

    @Autowired
    private SystemAttachmentService attachmentService;

    @Autowired
    private UserTaskService userTaskService;
    @Autowired
    private SystemConfigService systemConfigService;

    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<CourseProduction>
     * @author Mr.Zhang
     * @since 2022-07-22
     */
    @Override
    public PageInfo<CourseProductionResponse> getList(CourseProductionSearchRequest request, PageParamRequest pageParamRequest) {
        Page<CourseProduction> courseProductionPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 CourseProduction 类的多条件查询
        LambdaQueryWrapper<CourseProduction> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        CourseProduction model = new CourseProduction();
        BeanUtils.copyProperties(request, model);
        lambdaQueryWrapper.setEntity(model);
        if(request.getOrder().equals(1)){
            lambdaQueryWrapper.orderByDesc(CourseProduction::getCreateTime);
        }else{
            lambdaQueryWrapper.orderByDesc(CourseProduction::getLikeCount,CourseProduction::getCreateTime);
        }
        List<CourseProduction> courseProductions = dao.selectList(lambdaQueryWrapper);
        List<CourseProductionResponse> productionResponses = new ArrayList<>();
        if (CollectionUtil.isEmpty(courseProductions)) {
            return CommonPage.copyPageInfo(courseProductionPage, new ArrayList<>());
        }
        courseProductions.forEach(courseProduction -> {
            CourseProductionResponse response = new CourseProductionResponse();
            BeanUtils.copyProperties(courseProduction, response);
            productionResponses.add(response);
        });
        compareImgs(productionResponses);
        compareUserInfo(productionResponses);
        isLiked(productionResponses);
        return CommonPage.copyPageInfo(courseProductionPage, productionResponses);
    }

    private void isLiked(List<CourseProductionResponse> responses){
        List<Integer> productIds = responses.stream().map(CourseProductionResponse::getId).collect(Collectors.toList());
        Integer uid=userService.getUserId();
        if(uid.equals(0)){
            return;
        }
        LambdaQueryWrapper<CourseProductionLike> lqw=new LambdaQueryWrapper<>();
        lqw.eq(CourseProductionLike::getUid,uid);
        lqw.in(CourseProductionLike::getCourseProductionId,productIds);
        List<CourseProductionLike> productionLikes=productionLikeService.list(lqw);
        Set<Integer> productIdSet=productionLikes.stream().map(CourseProductionLike::getCourseProductionId).collect(Collectors.toSet());
        responses.forEach(response->{
            if(productIdSet.contains(response.getId())){
                response.setLiked(true);
            }
        });
    }

    private void compareUserInfo(List<CourseProductionResponse> courseProductions) {
        List<Integer> uids = courseProductions.stream().map(CourseProductionResponse::getUid).collect(Collectors.toList());
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.in(User::getUid, uids);
        List<User> users = userService.list(lqw);
        Map<Integer, User> userMap = users.stream().collect(Collectors.toMap(User::getUid, t -> t));
        courseProductions.forEach(resp -> {
            if (userMap.containsKey(resp.getUid())) {
                resp.setAvatar(userMap.get(resp.getUid()).getAvatar());
                resp.setNickname(userMap.get(resp.getUid()).getNickname());
            }
        });
    }

    private void compareImgs(List<CourseProductionResponse> courseProductions) {
        List<Integer> productionIds = courseProductions.stream().map(CourseProductionResponse::getId).collect(Collectors.toList());
        LambdaQueryWrapper<CourseProductionImg> lqw = new LambdaQueryWrapper<>();
        lqw.in(CourseProductionImg::getCourseProductionId, productionIds);
        List<CourseProductionImg> courseProductionImgs = courseProductionImgService.list(lqw);
        if (CollectionUtil.isEmpty(courseProductionImgs)) {
            return;
        }
        Map<Integer, List<CourseProductionImg>> map = courseProductionImgs.stream().collect(Collectors.groupingBy(CourseProductionImg::getCourseProductionId));
        courseProductions.forEach(courseProductionResponse -> {
            if (map.containsKey(courseProductionResponse.getId())) {
                List<String> imgPaths = map.get(courseProductionResponse.getId()).stream().map(CourseProductionImg::getImage).collect(Collectors.toList());
                courseProductionResponse.setImgPaths(imgPaths);
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> uploadProduction(CourseProductionRequest request) {
        if (CollectionUtil.isEmpty(request.getImgPaths())) {
            return CommonResult.failed("图片不能为空");
        }


        Integer uid = userService.getUserIdException();

        //图片上传类型 1本地 2七牛云 3OSS 4COS, 默认本地
        String uploadType = systemConfigService.getValueByKeyException("uploadType");
        Integer uploadTypeInt = Integer.parseInt(uploadType);
        String pre;
        String urlPrefix = systemConfigService.getValueByKey("localUploadUrl");
        switch (uploadTypeInt) {
            case 1:
                // 保存文件
//                multipartFile.transferTo(file);
                urlPrefix = systemConfigService.getValueByKey("localUploadUrl");
                break;
            case 2:
                pre = "qn";
                urlPrefix = systemConfigService.getValueByKeyException(pre + "UploadUrl");

                break;
            case 3:
                pre = "al";
                urlPrefix = systemConfigService.getValueByKeyException(pre + "UploadUrl");

                break;
            case 4:
                pre = "tx";
                urlPrefix = systemConfigService.getValueByKeyException(pre + "UploadUrl");
                break;
        }


        CourseProduction courseProduction = new CourseProduction();
        courseProduction.setCreateTime(new Date());
        courseProduction.setLikeCount(0);
        courseProduction.setUid(uid);
        courseProduction.setTitle(request.getTitle());
        courseProduction.setDescription(request.getDescription());
        courseProduction.setCourseId(request.getCourseId());
        courseProduction.setAudioFile(StringUtils.remove(request.getAudioFile(), urlPrefix + "/"));
        save(courseProduction);

        List<CourseProductionImg> imgList = new ArrayList<>();


        for (String imgPath : request.getImgPaths()) {
            CourseProductionImg img = new CourseProductionImg();
            img.setCourseProductionId(courseProduction.getId());
            img.setImage(imgPath);
            img.setImage(StringUtils.remove(imgPath, urlPrefix + "/"));
            img.setUid(uid);
            imgList.add(img);
        }

        courseProductionImgService.saveBatch(imgList);
        //todo 发布作品获得积分任务
        userTaskService.publicProductionTask(uid);
        return CommonResult.success();
    }

    @Override
    public CourseProductionResponse info(Integer productionId) {
        CourseProductionSearchRequest request = new CourseProductionSearchRequest();
        request.setId(productionId);
        PageParamRequest pageParamRequest = new PageParamRequest();
        PageInfo<CourseProductionResponse> pageInfo = getList(request, pageParamRequest);
        if(pageInfo.getSize()>0){
            return pageInfo.getList().get(0);
        }else {
            return null;
        }
    }

    @Override
    public CommonResult<String> deleteProduction(Integer courseProductionId) {
        Integer uid = userService.getUserIdException();
        CourseProduction courseProduction = getById(courseProductionId);
        if (ObjectUtil.isEmpty(courseProduction)) {
            return CommonResult.success();
        }
        if (courseProduction.getUid().equals(uid)) {
            removeById(courseProductionId);
            return CommonResult.success();
        } else {
            return CommonResult.failed("无法删除别人的作品");
        }
    }

}

